<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="xBYbf" id="xBYbf"><span data-lake-id="u5e93e300" id="u5e93e300">典型回答</span></h1>
  <p data-lake-id="u7ded83a0" id="u7ded83a0"><br></p>
  <p data-lake-id="ub89dd351" id="ub89dd351"><span data-lake-id="u9bd26643" id="u9bd26643">策略模式是一种行为设计模式，它允许在运行时根据不同情况选择算法的不同实现。它将算法和其相应的行为封装在一个独立的类中，使得它们可以相互替换，而不会影响客户端的使用。这种模式支持开闭原则，即在不修改现有客户端代码的情况下，可以动态地添加、删除或替换算法。</span></p>
  <p data-lake-id="u653e9ce7" id="u653e9ce7"><span data-lake-id="u0a6762e8" id="u0a6762e8">​</span><br></p>
  <p data-lake-id="uf2d1516d" id="uf2d1516d"><span data-lake-id="ub6d50af9" id="ub6d50af9">策略模式相较于if-else语句，有以下几个优势：</span></p>
  <ol list="ubbbe90e3">
   <li fid="ue47edda8" data-lake-id="ubf0b1ccb" id="ubf0b1ccb"><span data-lake-id="u59cb9cd4" id="u59cb9cd4">易于扩展：使用策略模式，可以方便地增加、删除或更换算法，而不需要修改原有的代码，只需要添加新的策略类即可。</span></li>
   <li fid="ue47edda8" data-lake-id="u2398fe04" id="u2398fe04"><span data-lake-id="ua13ab811" id="ua13ab811">更好的可读性：策略模式可以将复杂的条件语句分散到不同的策略类中，使得代码更加清晰、易于理解和维护。</span></li>
   <li fid="ue47edda8" data-lake-id="ua88380c1" id="ua88380c1"><span data-lake-id="u357170d8" id="u357170d8">避免大量的条件判断：在if-else语句中，可能需要写很多的条件判断，当条件越来越多时，代码变得复杂、难以维护。而使用策略模式，可以将条件判断分散到不同的策略类中，每个策略类只需要关注自己的逻辑，使得代码更加简洁。</span></li>
   <li fid="ue47edda8" data-lake-id="u128f30dc" id="u128f30dc"><span data-lake-id="u34784418" id="u34784418">提高代码复用性：策略模式可以将一些常用的算法封装在策略类中，可以被多个客户端共享使用，从而提高代码的复用性。</span></li>
  </ol>
  <p data-lake-id="u41569741" id="u41569741"><span data-lake-id="u4e643310" id="u4e643310">​</span><br></p>
  <p data-lake-id="u5495e954" id="u5495e954"><span data-lake-id="u2a526ccd" id="u2a526ccd">一般在实际应用中，策略模式会结合工厂模式、模板方法模式一起使用。</span></p>
  <p data-lake-id="u2d88cd8a" id="u2d88cd8a"><span data-lake-id="ue9f31610" id="ue9f31610">​</span><br></p>
  <p data-lake-id="u51d5b690" id="u51d5b690"><span data-lake-id="u15b452cd" id="u15b452cd">​</span><br></p>
  <h1 data-lake-id="hoZPf" id="hoZPf"><span data-lake-id="u41d128c5" id="u41d128c5">扩展知识</span></h1>
  <p data-lake-id="ud2c66574" id="ud2c66574"><br></p>
  <h2 data-lake-id="zX0RL" id="zX0RL"><span data-lake-id="udfa20248" id="udfa20248">示例</span></h2>
  <p data-lake-id="u151de5ed" id="u151de5ed"><br></p>
  <p data-lake-id="ufdce958d" id="ufdce958d"><span data-lake-id="uaa32e64a" id="uaa32e64a">我们结合策略+工厂+模板方法模式，看一下如何在Spring中使用。</span></p>
  <p data-lake-id="u8cdf320b" id="u8cdf320b"><span data-lake-id="u57af206d" id="u57af206d">​</span><br></p>
  <p data-lake-id="u43e56881" id="u43e56881"><span data-lake-id="u149ed925" id="u149ed925">假设有一个订单处理系统，处理订单的流程包括如下步骤：</span></p>
  <ol list="u76c4a85f">
   <li fid="u71745668" data-lake-id="u3b0351ae" id="u3b0351ae"><span data-lake-id="u395ef09b" id="u395ef09b">根据订单类型选择不同的处理策略（如普通订单、团购订单、秒杀订单等）；</span></li>
   <li fid="u71745668" data-lake-id="u23455999" id="u23455999"><span data-lake-id="u30032354" id="u30032354">每个订单类型的处理策略可能有所不同，但是都需要经过一些公共的处理流程，比如记录日志、验证订单信息等；</span></li>
   <li fid="u71745668" data-lake-id="u9eec1302" id="u9eec1302"><span data-lake-id="u75311e32" id="u75311e32">处理完订单后，需要将处理结果返回给调用方。</span></li>
  </ol>
  <p data-lake-id="u2a21de56" id="u2a21de56"><span data-lake-id="u2da80c85" id="u2da80c85">​</span><br></p>
  <p data-lake-id="u2e60e8a4" id="u2e60e8a4"><span data-lake-id="u92638e50" id="u92638e50">首先，定义订单处理策略的接口：</span></p>
  <p data-lake-id="u5b048b33" id="u5b048b33"><span data-lake-id="uab547c77" id="uab547c77">​</span><br></p>
  <pre lang="java"><code>
public interface OrderProcessStrategy {
    void process(Order order);
}
</code></pre>
  <p data-lake-id="uf160cffb" id="uf160cffb"><br></p>
  <p data-lake-id="ue7c13dbf" id="ue7c13dbf"><span data-lake-id="u3eda5956" id="u3eda5956">然后定义一个公共的基础实现类，其中包含了订单的前置处理和后置处理：</span></p>
  <p data-lake-id="ue8f37f4d" id="ue8f37f4d"><span data-lake-id="uad177419" id="uad177419">​</span><br></p>
  <pre lang="java"><code>
public abstract class BaseOrderProcessStrategy implements OrderProcessStrategy {
   public void process(Order order){
    	//前置处理
    	checkOrder(order);

    	doProcess(order);

    	//后置处理
      //doLog(order);
  	
    }

  	public abstract void doProcess(Order order);
    public void checkOrder(Order order){
    	//订单检查业务逻辑
    }

	 public void doLog(Order order){
    	//记录日志相关代码
    }
}
</code></pre>
  <p data-lake-id="u041c7d81" id="u041c7d81"><br></p>
  <p data-lake-id="uf30c9271" id="uf30c9271"><span data-lake-id="u24426877" id="u24426877">接下来，定义不同类型订单的处理策略实现类，集成BaseOrderProcessStrategy这个抽象类，并且实现其中的doProcess方法。</span></p>
  <p data-lake-id="uca03662a" id="uca03662a"><span data-lake-id="u4c95571e" id="u4c95571e">​</span><br></p>
  <pre lang="java"><code>
@Component("normalOrderProcessStrategy")
public class NormalOrderProcessStrategy extends BaseOrderProcessStrategy {
    @Override
    public void doProcess(Order order) {
        // 普通订单处理逻辑
    }
}

@Component("groupOrderProcessStrategy")
public class GroupOrderProcessStrategy extends BaseOrderProcessStrategy {
    @Override
    public void doProcess(Order order) {
        // 团购订单处理逻辑
    }
}

@Component("seckillOrderProcessStrategy")
public class SeckillOrderProcessStrategy extends BaseOrderProcessStrategy {
    @Override
    public void doProcess(Order order) {
        // 秒杀订单处理逻辑
    }
}

</code></pre>
  <p data-lake-id="ubfbbaefc" id="ubfbbaefc"><br></p>
  <p data-lake-id="u3cc0bf54" id="u3cc0bf54"><span data-lake-id="u3a69560d" id="u3a69560d">然后，定义一个工厂类来创建订单处理策略实例：</span></p>
  <p data-lake-id="udc7fcb2c" id="udc7fcb2c"><span data-lake-id="u8c252e94" id="u8c252e94">​</span><br></p>
  <pre lang="java"><code>
@Component
public class OrderProcessStrategyFactory {
    @Autowired
    private ApplicationContext applicationContext;

    public OrderProcessStrategy getStrategy(String type) {
        return applicationContext.getBean(type + "OrderProcessStrategy", OrderProcessStrategy.class);
    }
}
</code></pre>
  <p data-lake-id="ud5c2cb75" id="ud5c2cb75"><span data-lake-id="u5c709c86" id="u5c709c86">​</span><br></p>
  <p data-lake-id="u71723f7f" id="u71723f7f"><span data-lake-id="u259a35bb" id="u259a35bb">或者：</span></p>
  <pre lang="java"><code>

public static class OrderProcessStrategyFactory {
    @Autowired
    private ConcurrentHashMap&lt;String,OrderProcessStrategy&gt; orderProcessStrategyMaps;

    public OrderProcessStrategy getStrategy(String type) {
        return orderProcessStrategyMaps.get(type + "OrderProcessStrategy");
    }
}
</code></pre>
  <p data-lake-id="ud84f15f0" id="ud84f15f0"><span data-lake-id="ud75359e3" id="ud75359e3">​</span><br></p>
  <p data-lake-id="u5989e6eb" id="u5989e6eb"><span data-lake-id="u939e5278" id="u939e5278">最后，定义一个订单处理服务类，使用策略模式来处理订单：</span></p>
  <p data-lake-id="u09f2ea8b" id="u09f2ea8b"><span data-lake-id="ucc0f0a16" id="ucc0f0a16">​</span><br></p>
  <pre lang="java"><code>
@Service
public class OrderProcessService {
    @Autowired
    private OrderProcessStrategyFactory strategyFactory;

    public void processOrder(Order order) {
        // 选择处理策略
        OrderProcessStrategy strategy = strategyFactory.getStrategy(order.getType());

        // 执行处理流程
        strategy.process(order);
    }
}
</code></pre>
  <p data-lake-id="ufb690364" id="ufb690364"><span data-lake-id="uf9f443c1" id="uf9f443c1" class="lake-fontsize-12" style="color: rgb(55, 65, 81); background-color: rgb(247, 247, 248)">​</span><br></p>
  <p data-lake-id="u795e4bd1" id="u795e4bd1"><span data-lake-id="u6152e07a" id="u6152e07a">上述代码中，通过使用工厂模式来创建不同类型的订单处理策略实例，并使用策略模式来处理订单，避免了复杂的 if-else 语句，代码更加简洁易读，也更加易于维护。同时，使用模板方法模式来封装公共的处理流程，避免了代码重复。</span></p>
 </body>
</html>